#ifndef TCPMANAGER_H
#define TCPMANAGER_H

#include "global.h"
#include "singleton.h"
#include "userdata.h"

#include <QObject>
#include <QTcpSocket>
#include <QString>

class TcpManager : public QObject, public Singleton<TcpManager>, public std::enable_shared_from_this<TcpManager>
{
    Q_OBJECT

    friend class Singleton<TcpManager>;
public:
    ~TcpManager() {

    }

private:
    TcpManager();


    // 处理ID_CHAT_LOGIN_RSP(登陆聊天服务器回包)
    void handleChatLoginRsp(ReqId id, QByteArray data);
    // 处理ID_SEARCH_USER_RSP(搜索用户回包)
    void handleSearchUserRsp(ReqId id, QByteArray data);
    // 处理ID_NOTIFY_ADD_FRIEND_REQ(通知用户添加好友申请)
    void handleNotifyAddFriendReq(ReqId id, QByteArray data);
    // 处理ID_NOTIFY_AUTH_FRIEND_REQ((通知用户认证好友申请))
    void handleNotifyAuthFriendReq(ReqId id, QByteArray data);
    // 处理ID_ADD_FRIEND_RSP(申请添加好友的回复)
    void handleAddFriendRsp(ReqId id, QByteArray data);
    // 处理ID_AUTH_FRIEND_RSP(认证好友回复)
    void handleAuthFriendRsp(ReqId id, QByteArray data);
    // 处理ID_TEXT_CHAT_MSG_RSP(文本聊天信息回复)
    void handleTextChatMsgRsp(ReqId id, QByteArray data);
    // 处理ID_NOTIFY_TEXT_CHAT_MSG_REQ(通知用户文本聊天信息)
    void handleNotifyTextChatMsgReq(ReqId id, QByteArray data);

    // 注册消息的回调
    void initHandlers();
    // 调用消息的会回调来处理数据
    void handleMsg(ReqId id, QByteArray data);

public slots:
    // 处理Tcp连接
    void slot_tcp_connect(ServerInfo sever_info);
    // 处理数据发送
    void slot_send_data(ReqId req_id, QByteArray data_bytes);

signals:
    // Tcp连接建立成功之后，发送切换消息发送界面的信号
    void sig_con_success(bool b_success);
    // Tcp连接建立成功之后，通知消息界面可以发送消息的信号
    void sig_send_data(ReqId id, QByteArray data);
    // 发送登录失败的信号
    void sig_login_failed(int);
    // 发送切换聊天界面的信号
    void sig_swich_chatdlg();
    // 搜索联系人的信号（成功或者失败）
    void sig_user_search(std::shared_ptr<SearchInfo>);
    // 申请添加好友的信号(传递好友的信息)
    void sig_friend_apply(std::shared_ptr<AddFriendApply>);
    // 对方同意添加好友的信号
    void sig_add_auth_friend(std::shared_ptr<AuthInfo>);
    // 同意添加对方为好友的信号
    void sig_auth_rsp(std::shared_ptr<AuthRsp>);
    // 提示新消息传来的信号
    void sig_text_chat_msg(std::shared_ptr<TextChatMsg> msg);

private:
    QTcpSocket m_socket;
    QString m_host;
    quint16 m_port;
    QByteArray m_buffer;
    bool m_b_recv_pending; // 标志数据包是否收全
    quint16 m_message_id;
    quint16 m_message_len;
    QMap<ReqId, std::function<void(ReqId id, QByteArray data)>> m_handlers;
};

#endif // TCPMANAGER_H
